#  Top level GNUmakefile for windows builds
#
#  It includes makefiles/*.mk for windows buildtype rules
#  and sources(windows style makefile). it doesn't depend on 
#  Makerules.env except to get SRCBASE if not yet defined. 
#
#  $Id: GNUmakefile.inc,v 1.103.50.2 2009-08-18 18:42:30 Exp $

SHELL=bash
export SHELL
unexport C_DEFINES
HOSTNAME=$(shell hostname)
ERRORS :=
WARNINGS :=
comma:= ,
empty:=
space:= $(empty) $(empty)

ifdef ECLOUD_BUILD_ID
  CMDSHELL := $(subst \,/,$(COMSPEC))
  CMDSTART := $(CMDSHELL) /c start /min /separate
else # ECLOUD_BUILD_ID
  CMDSHELL :=
  CMDSTART :=
endif # ECLOUD_BUILD_ID

### if SRCBASE is not defined, set it to wherever Makerules.env is found
ifndef SRCBASE
    ifneq ($(wildcard ../Makerules.env), )
	SRCBASE	= ../
    else	
	ifneq ($(wildcard ../../Makerules.env), )
		SRCBASE	= ../..
	else
	    ifneq ($(wildcard ../../../Makerules.env),)
		    SRCBASE	= ../../..
	    else
		ifneq ($(wildcard ../../../../Makerules.env),)
			SRCBASE	= ../../../..
		else
		ifneq ($(wildcard ../../../../../Makerules.env),)
		    SRCBASE = ../../../../..
		else
		    ifneq ($(wildcard ../../../../../../Makerules.env),)
			    SRCBASE = ../../../../../..
		    endif
	    endif
		endif
	    endif
	endif
    endif
endif # ifndef SRCBASE 

ifeq ($(strip $(SRCBASE)), )
    ERRORS += "SRCBASE is not defined!"
    ERRORS += "This variable must be defined in your sources or GNUsources file,"
    ERRORS += "or it may be calculated provided you are in a CVS source repository,"
    ERRORS += "and you are not too far below the root."
endif

### if TTYPE is not defined, reinvoke this same makefile with TTYPE defined
###retail:free:   --> $(MAKE) -f $(SRCBASE)/GNUmakefile.inc TTYPE=OPT all
###debug:checked: --> $(MAKE) -f $(SRCBASE)/GNUmakefile.inc TTYPE=DBG all
###%:             --> $(MAKE) -f $(SRCBASE)/GNUmakefile.inc TTYPE=DBG MAKECMDGOALS=$@ $@

ifeq ($(origin TTYPE), undefined)

all : debug free

release : all

unexport SRCFILE
ifndef SRCFILE
	SRCFILE = ./sources
endif
include $(SRCFILE)

#   In some rare instances you may want to have the makefile synthesize
#   explicit rules for all of your source files.  You must do this if you
#   are building a target with multiple source files of the same name,
#   e.g. ./utils.c and ../ntddksim/utils.c.  You might also want to use
#   this method if you don't want to use VPATHs.
#
ifdef USE_SRCRULES

SRCRULES=$(SRCFILE).mk
SOURCES.CPP	:= $(filter %.cpp %.CPP,$(SOURCES))
SOURCES.C	:= $(filter %.c %.C,$(SOURCES))

$(SRCRULES) : $(SRCFILE)
	@echo "building explicit source rules..."
	@( \
	echo "# DO NOT EDIT!!!!  DO NOT EDIT!!!!  DO NOT EDIT!!!!"; \
	echo "# This file is automatically generated."; \
	echo "#"; \
	$(foreach f,$(SOURCES.C), echo '$$(OUTDIR_$$(TTYPE))/$(patsubst %.c,%.obj,$(subst /,_,$(f))) : $(f)'; echo '	$$(c-obj-command)'; echo;) \
	$(foreach f,$(SOURCES.CPP), echo '$$(OUTDIR_$$(TTYPE))/$(patsubst %.cpp,%.obj,$(subst /,_,$(f))) : $(f)'; echo '	$$(cpp-obj-command)'; echo;) \
	) >$(SRCFILE).mk

$(SRCFILE) :
	echo making $@

retail free :: $(SRCRULES)

debug checked :: $(SRCRULES)

endif # USE_SRCRULES

#
# End of rule synthesis section
#

retail free ::
	$(MAKE) -f $(SRCBASE)/GNUmakefile.inc TTYPE=OPT all

debug checked :: 
	$(MAKE) -f $(SRCBASE)/GNUmakefile.inc TTYPE=DBG all

%GNUmakefile.inc :
	echo making $@

GNUmakefile :
	echo making $@

clean : 
	$(MAKE) -f $(SRCBASE)/GNUmakefile.inc TTYPE=DBG MAKECMDGOALS=$@ $@

## This catch-all generic rule breaks make targets defined in module which 
## call this makefile.
## % : FORCE
## 	$(MAKE) -f $(SRCBASE)/GNUmakefile.inc TTYPE=DBG MAKECMDGOALS=$@ $@

.PHONY: all release free checked retail debug clean FORCE


### if TTYPE is defined, 
###   define commands, tools and compile rules
###   include $(SRCFILE)
###   build all :: target ::
else # TTYPE is defined

# Define default command for printing errors and warnings.  This will
# be redefined at the end of this makefile if any errors or warnings
# are encountered.  
#
define print-errors
endef

define print-warnings
endef

# define the default command for compiling .c files into .obj files.
# Some target types will redefine this command.
#
# %.obj :  %.c
define c-obj-command
    $(CC) -c $(C$(TTYPE)FLAGS) -I$(OUTDIR_$(TTYPE)) $(CPPFLAGS) $(F$(TTYPE)) -Fo$@ $<
endef

# define the default command for compiling .cpp files into .obj files.
# Some target types will redefine this command.
#
# %.obj :  %.cpp
define cpp-obj-command
    $(CC) -c $(C$(TTYPE)FLAGS) -I$(OUTDIR_$(TTYPE)) $(CPPFLAGS) $(F$(TTYPE)) -Fo$@ $<
endef

# define the default command for compiling .asm files into .obj files.
# Some target types will redefine this command.
#
# %.obj :  %.asm
define asm-obj-command
	$(AS) -c $(AFLAGS) $(CPPFLAGS) $(F$(TTYPE)) -Fo$@ $<
endef

# define the default command for compiling .rc files into .res files.
# Some target types will redefine this command.
#
# %.res :  %.rc
define rc-res-command
	export INCLUDE="$(OUTDIR_$(TTYPE));$(MSINCLUDE)"; \
	$(CMDSTART) $(RC) -r $(RCFLAGS) -fo$@ $<
endef

all ::
	$(print-warnings)
ifdef SHOWBUILDINFO
	@echo " -------------------------------------------"
	@echo " SRCFILE      = $(SRCFILE)"
	@echo " SOURCES      = $(SOURCES)"
	@echo " C_DEFINES    = $(C_DEFINES)"
	@echo " WLTUNEFILE   = $(WLTUNEFILE)"
	@echo " TARGETPATH   = $(TARGETPATH)"
	@echo " TARGETTYPE   = $(TARGETTYPE)"
	@echo " MAKE_VERSION = $(MAKE_VERSION)"
	@echo " TTYPE        = $(subst OPT,OPT(free),$(subst DBG,DBG(checked),$(TTYPE)))"
	@echo " -------------------------------------------"
endif # SHOWBUILDINFO

all ::
	$(print-errors)

include $(SRCBASE)/branding.inc

ifeq ($(origin USEBCMUIO), undefined)
#if defined(USEBCMUIO)
USEBCMUIO=1
#else
# undefine USEBCMUIO
USEBCMUIO=
#endif
endif

BIN_OPT=retail
BIN_DBG=debug
BUILDENV_OPT=free
BUILDENV_DBG=checked
MSVSBUILDENV_OPT=Release
MSVSBUILDENV_DBG=Debug
OUTDIR_OPT = $(TARGETPATH)/free
OUTDIR_DBG = $(TARGETPATH)/checked

OUTDIR_FREE = $(OUTDIR_OPT)
OUTDIR_CHECKED = $(OUTDIR_DBG)


CC  = cl
AS  = ml
RC  = rc
MC  = mc
LD  = link
LIBCMD = lib
MTL = midl

# Ignore any include path and lib paths that the user imports from 
# the environment.
#
INCLUDE =

ifeq ($(origin TARGETPATH), undefined)
    TARGETPATH=.
endif
TARGETPATH := $(subst \,/,$(TARGETPATH))

DDKBUILDENV := $(BUILDENV_$(TTYPE))
MSVSBUILDENV := $(MSVSBUILDENV_$(TTYPE))
BIN         := $(BIN_$(TTYPE))
MC_FLAGS = -v

### assume sources as entry point
ifndef SRCFILE
	SRCFILE=./sources
endif

include $(SRCFILE)
SRCRULES=$(SRCFILE).mk

ifeq ($(findstring $(TARGETTYPE), "EXE DRIVER LIB DLL DLL16 EXE16 DYNLINK VXD DOSEXE PROGRAM DUMMY"), )
	ERRORS += "TARGETTYPE is not defined or not recognized!"
	ERRORS += "This variable must be defined with a recognized value"
	ERRORS += "in your sources or GNUsources file."
endif

# include any branding defined if they exist in the environment
ifneq ($(BRAND),)
    C_DEFINES += -DBRAND="'$(BRAND)'"
endif # BRAND

SOURCES.IDL	:= $(filter %.idl,$(SOURCES))
SOURCES.TLB	:= $(patsubst %.idl,%.tlb,$(SOURCES.IDL))
SOURCES._IC     := $(patsubst %.idl,%_i.c,$(SOURCES.IDL))

SOURCES.OBJ	:= $(SOURCES)
SOURCES.OBJ	:= $(patsubst %.cpp,%.obj,$(SOURCES.OBJ))
SOURCES.OBJ	:= $(patsubst %.CPP,%.obj,$(SOURCES.OBJ))
SOURCES.OBJ	:= $(patsubst %.asm,%.obj,$(SOURCES.OBJ))
SOURCES.OBJ	:= $(patsubst %.ASM,%.obj,$(SOURCES.OBJ))
SOURCES.OBJ	:= $(patsubst %.c,%.obj,$(SOURCES.OBJ))
SOURCES.OBJ	:= $(patsubst %.C,%.obj,$(SOURCES.OBJ))
SOURCES.OBJ	:= $(filter %.obj,$(SOURCES.OBJ))
# SOURCES.OBJ	:= $(notdir $(SOURCES.OBJ))
SOURCES.OBJ	:= $(subst /,_,$(SOURCES.OBJ))

SOURCES.RES	:= $(patsubst %.rc,%.res,$(filter %.rc,$(SOURCES)))
SOURCES.MSG	:= $(patsubst %.mc,%.h,$(filter %.mc,$(SOURCES)))

vpath %.rc 	.:..:../..


ifdef USE_DEPENDENCIES

# MAKECMDGOALS is not supported until gnumake version 3.76 so we hack
# it by explicitly setting MAKECMDGOALS in the clean rule at the top
# of this file.  
#
ifneq ($(MAKECMDGOALS),clean)

# BUG -- BUG -- BUG
# This code assumes that files are still unique without the extension.
# So no foo.c and foo.cpp in the same makefile.

SOURCES.D       :=  $(SOURCES)
SOURCES.D       :=  $(patsubst %.c,%.d,$(SOURCES.D))
SOURCES.D       :=  $(patsubst %.C,%.d,$(SOURCES.D))
SOURCES.D       :=  $(patsubst %.cpp,%.d,$(SOURCES.D))
SOURCES.D       :=  $(patsubst %.CPP,%.d,$(SOURCES.D))
SOURCES.D       :=  $(filter %.d,$(SOURCES.D))

endif  # MAKECMDGOALS != clean

endif  # ifdef USE_DEPENDENCIES

SI_FLAGS = -translate:always,source,package 



# Target all just depends upon our target file.
all :: target post-build-target

# The target file depends upon the directory where it will reside.
target :: $(OUTDIR_$(TTYPE))/NUL

WLCFGDIR        ?= $(SRCBASE)/wl/config
WLTUNEFILE      ?= wltunable_sample.h

# Create target directory if necessary.
$(OUTDIR_$(TTYPE))/NUL : 
	[ -d "$(@D)" ] || mkdir -p $(@D)
ifeq ($(WLCONF_GEN),true)
	@if [ ! -f "$(@D)/wlconf.h" ]; then \
	    cp -v $(WLCFGDIR)/$(WLTUNEFILE) $(@D)/wlconf.h; \
	elif ! diff -q $(WLCFGDIR)/$(WLTUNEFILE) $(@D)/wlconf.h; then \
	    cp -v $(WLCFGDIR)/$(WLTUNEFILE) $(@D)/wlconf.h; \
	fi
endif

#
# If the sources file specified a NTTARGETFILE0, build that first.
#
target :: $(NTTARGETFILE0)


# calculate some dynamic variables that are useful in build rules.
#
DEPS_OBJ = $(patsubst %,$(OUTDIR_$(TTYPE))/%,$(SOURCES.OBJ))
DEPS_RES = $(patsubst %,$(OUTDIR_$(TTYPE))/%,$(SOURCES.RES))
DEPS_TLB = $(patsubst %,$(OUTDIR_$(TTYPE))/%,$(SOURCES.TLB))
DEPS_MSG = $(patsubst %,$(OUTDIR_$(TTYPE))/%,$(SOURCES.MSG))
# Finally generate DEPENDENCIES list that are made as explicit dependencies
# in src/makefile/<obj-type>.mk file
DEPENDENCIES =    $(DEPS_TLB) $(DEPS_MSG) $(DEPS_OBJ) $(DEPS_RES)
DOS_DEPS= $(shell echo $(filter-out %.tlb %.TLB %.h %.H %.def %.DEF,$^) | sed 's%//\(.\)/%\1:/%g')


$(OUTDIR_$(TTYPE))/%.i :  %.c
	@echo "Compiling $(notdir $<) -> $(notdir $@)"
	$(CC) -E -P $(C$(TTYPE)FLAGS) $(CPPFLAGS) $(F$(TTYPE)) $< >$@ 

$(OUTDIR_$(TTYPE))/%.i :  %.cpp
	@echo "Compiling $(notdir $<) -> $(notdir $@)"
	$(CC) -E -P $(C$(TTYPE)FLAGS) $(CPPFLAGS) $(F$(TTYPE)) $< >$@ 

$(OUTDIR_$(TTYPE))/%.d :  %.c
	@echo "Compiling $(notdir $<) -> $(notdir $@)"
	$(calculate_dependencies)

$(OUTDIR_$(TTYPE))/%.d :  %.C
	@echo "Compiling $(notdir $<) -> $(notdir $@)"
	$(calculate_dependencies)

$(OUTDIR_$(TTYPE))/%.d :  %.cpp
	@echo "Compiling $(notdir $<) -> $(notdir $@)"
	$(calculate_dependencies)

$(OUTDIR_$(TTYPE))/%.d :  %.CPP
	@echo "Compiling $(notdir $<) -> $(notdir $@)"
	$(calculate_dependencies)

$(OUTDIR_$(TTYPE))/%.obj :  %.c
	@echo "Compiling $(notdir $<) -> $(notdir $@)"
	$(c-obj-command)

$(OUTDIR_$(TTYPE))/%.obj :  $(OUTDIR_$(TTYPE))/%.c
	@echo "Compiling $(notdir $<) -> $(OUTDIR_$(TTYPE))/$(notdir $@)"
	$(c-obj-command)

$(OUTDIR_$(TTYPE))/%.obj :  %.C
	@echo "Compiling $(notdir $<) -> $(notdir $@)"
	$(c-obj-command)

$(OUTDIR_$(TTYPE))/%.obj :  %.cpp
	@echo "Compiling $(notdir $<) -> $(notdir $@)"
	$(cpp-obj-command)

$(OUTDIR_$(TTYPE))/%.obj :  %.CPP
	@echo "Compiling $(notdir $<) -> $(notdir $@)"
	$(cpp-obj-command)

ifdef ECLOUD_BUILD_ID
$(OUTDIR_$(TTYPE))/%.res :  RC = rc
endif # ECLOUD_BUILD_ID

$(OUTDIR_$(TTYPE))/%.res :  %.rc
	@echo "Compiling $(notdir $<) -> $(notdir $@)"
	$(rc-res-command)

# build rule for IDL files.
$(OUTDIR_$(TTYPE))/%.tlb $(OUTDIR_$(TTYPE))/%.h $(OUTDIR_$(TTYPE))/%_i.c : %.idl
	@echo "Compiling $(notdir $<) -> $(notdir $@)"
	$(MTL) /I $(MSSDK)/include /nologo /Oicf /out $(OUTDIR_$(TTYPE)) $<

# Build rule for message file
$(OUTDIR_$(TTYPE))/%.rc $(OUTDIR_$(TTYPE))/%.h : %.mc
	@echo "Compiling $(notdir $<) -> $(notdir $@)"
	$(MC) -h $(OUTDIR_$(TTYPE)) -r $(OUTDIR_$(TTYPE)) $(MC_FLAGS) $<

$(OUTDIR_$(TTYPE))/%.obj: %.asm
	@echo "Compiling $(notdir $<) -> $(notdir $@)"
	$(asm-obj-command)

FORCE: 

clean ::
	rm -rf $(OUTDIR_CHECKED) $(OUTDIR_FREE) $(SRCRULES)


ifeq  ("$(TARGETTYPE)", "DRIVER")
ifeq  ("$(DRIVERTYPE)", "WDM")
include $(SRCBASE)/makefiles/wdm.mk
else
ifeq  ("$(DRIVERTYPE)", "WDM2600")
    include $(SRCBASE)/makefiles/wdm2600.mk
else
    include $(SRCBASE)/makefiles/driver.mk
endif
endif 
endif 

ifeq  ("$(TARGETTYPE)", "VXD")
include $(SRCBASE)/makefiles/vxd.mk
endif 

ifneq ($(findstring x$(TARGETTYPE)x, "xDLLx xDYNLINKx"), )
ifneq ($(findstring x$(HOSTOS)x, "xwincex"), )
include $(SRCBASE)/makefiles/dllce.mk
else
include $(SRCBASE)/makefiles/dll.mk
endif
endif 

ifneq ($(findstring $(TARGETTYPE)x, "DLL16x"), )
include $(SRCBASE)/makefiles/dll16.mk
endif 

ifneq ($(findstring $(TARGETTYPE)x, "EXE16x"), )
include $(SRCBASE)/makefiles/exe16.mk
endif 

ifneq ($(findstring $(TARGETTYPE), "LIB"), )
ifneq ($(findstring x$(HOSTOS)x, "xwincex"), )
include $(SRCBASE)/makefiles/libce.mk
else
include $(SRCBASE)/makefiles/lib.mk
endif
endif

ifneq ($(findstring $(TARGETTYPE), "xEXEx xPROGRAMx"), )
ifneq ($(findstring x$(HOSTOS)x, "xwincex"), )
include $(SRCBASE)/makefiles/exece.mk
else
include $(SRCBASE)/makefiles/exe.mk
endif
endif 

ifneq ($(findstring x$(TARGETTYPE)x, "xDOSEXEx"), )
include $(SRCBASE)/makefiles/dosexe.mk
endif

ifneq ($(findstring $(TARGETTYPE), "DUMMY"), )
include $(SRCBASE)/makefiles/dummy.mk
endif

# Set make variables that help find things like DDK's, SDK's, etc,
# depending upon the requirements expressed in the individual
# makefile(s).
include $(SRCBASE)/makefiles/env.mk

# 
# Add some rules so that our target depends on any libraries we are going 
# to link against.
#
#target :: $(LIBS)


target :: $(OUTDIR_$(TTYPE))/$(TARGET)

ifneq ($(wildcard ./makefile.inc), )
include .\makefile.inc
endif


#
# If the sources file specified a NTTARGETFILES, build that last.
#

target :: $(NTTARGETFILES)


target :: 
	@echo Finished compiling $@
	@echo ""

post-build-target ::

release: all

.PHONY: all target release clean $(OUTDIR_$(TTYPE))/.depends 

ifneq ($(wildcard $(SRCRULES)), )
include $(SRCRULES)
endif

# only try to do dependency checking if we have some dependencies to check!
#
# It seems counter-intiutive but it looks like the
# include dependencies are evaluated in reverse order from their
# appearance in the makefile.  Therefore we include the NUL file from
# the object directory *after* we include the dependency files
# themselves.  This results in the object directory getting created
# before we build any of the dependency files.
#
ifneq ($(strip $(SOURCES.D)),)
include $(patsubst %,$(OUTDIR_$(TTYPE))/%,$(SOURCES.D))
include $(OUTDIR_$(TTYPE))/NUL 
endif

define calculate_dependencies
	@ echo making $@
	$(SHELL) -ec 'gcc -MM -w -D_M_IX86=500 $(C_DEFINES) $(CPPFLAGS) $< \
	| sed '\''s?$*\.o[ :]*?$@ &?g'\'' >$@'
endef

# OTHER_SOURCES_PROCESSED removes recursive build of OTHER_SOURCES, when that
# switch is set from cmd line
ifdef OTHER_SOURCES
ifndef OTHER_SOURCES_PROCESSED
all clean :: $(OTHER_SOURCES)
	@echo "Go through OTHER_SOURCES: $(OTHER_SOURCES)"
	$(foreach SRCFILE,$(OTHER_SOURCES),$(MAKE) SRCFILE=$(SRCFILE) TTYPE=$(TTYPE) OTHER_SOURCES_PROCESSED=true $@; )
endif # OTHER_SOURCES_PROCESSED
endif # OTHER_SOURCES

vpath %.Lib $(LIBVPATH)
vpath %.LIB $(LIBVPATH)
vpath %.lib $(LIBVPATH)

export PATH:=$(subst $(space),:,$(strip $(NEWPATH))):$(PATH)

foo: 
	@echo _SDKROOT=$(_SDKROOT)
	@echo NEWPATH=$(NEWPATH)

endif 
###  end of ifeq ($(origin TTYPE), undefined)

printenv:
	env

ifdef WARNING
define print-warnings
@echo "Warning **** Warning **** Warning **** Warning **** Warning"
@for warn in $(WARNING) ; do echo $$warn; done
@echo "Continuing..."
endef
endif # WARNING

ifdef ERRORS
define print-errors
@echo "Error **** Error **** Error **** Error **** Error"
@for err in $(ERRORS) ; do echo $$err; done
@echo "Exiting makefile."
@exit 1
endef
endif # ERRORS
